// author : sb hwang
// date : 2012.05.15
// draw bmp image -> target board

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <fcntl.h>
#include <sys/ioctl.h>
#include <sys/mman.h>
#include <linux/fb.h>
#include "bmplib.h"

#define MIN(x, y) ((x) > (y) ? (y) : (x))

#define FBDEV	"/dev/fb"

#define IU		"./bmp/iu.bmp"
#define BGI		"./bmp/bgimg.bmp"
#define II		"./bmp/1-1.bmp"
#define III		"./bmp/1-2.bmp"
#define IV		"./bmp/1-3.bmp"
#define V		"./bmp/1-4.bmp"
#define VI		"./bmp/1-5.bmp"

typedef unsigned char ubyte;

static unsigned short makepixel(struct fb_var_screeninfo *pfbvar, ubyte r, ubyte g, ubyte b)
{
	unsigned short rnew, gnew, bnew;
	rnew = r >> (8-pfbvar->red.length);
	gnew = g >> (8-pfbvar->green.length);
	bnew = b >> (8-pfbvar->blue.length);

	return (unsigned short)((rnew << pfbvar->red.offset) | (gnew << pfbvar->green.offset) | (bnew << pfbvar->blue.offset));

}

int updateScreen(int mode)
{
	int fbfd;
	unsigned short *pfbmap;
	struct fb_var_screeninfo fbvar;
	int i,j;
	struct bgrpixel pixel;
	bmphandle_t bh;
	
	int offset_x=0;
	int offset_y=0;

	printf("g_mode = %d\n",mode);
	switch(mode)
	{
		case 0:
			bh = bmp_open(BGI);
			break;
		case 101:
			bh = bmp_open(VI);
			offset_x=50;
			offset_y=100;
			break;
		case 102:
			bh = bmp_open(II);
			offset_x=50;
			offset_y=100;
			break;
		case 103:
			bh = bmp_open(III);
			offset_x=50;
			offset_y=100;
			break;
		case 104:
			bh = bmp_open(IV);
			offset_x=50;
			offset_y=100;
			break;
		default:
			bh = bmp_open(V);
			offset_x=50;
			offset_y=100;
			break;
	}
		
	fbfd = open(FBDEV, O_RDWR);
	if(fbfd < 0)
	{
		perror("fbdev open");
		return 1;
	}

	if(ioctl(fbfd, FBIOGET_VSCREENINFO, &fbvar) < 0)
	{
		perror("fbdev ioctl");
		return 1;
	}

	if(fbvar.bits_per_pixel != 16)
	{
		printf("bpp is not 16\r\n");
		return 1;
	}

	pfbmap = (unsigned short*)mmap(0, fbvar.xres*fbvar.yres*16/8,
			PROT_READ | PROT_WRITE, MAP_SHARED, fbfd, 0);

	if((unsigned)pfbmap == (unsigned)-1)
	{
		perror("fbdev mmap");
		return 1;
	}

	for(i=0; i<MIN(bmp_height(bh), fbvar.yres); i++)
	{
		for(j=0; j<MIN(bmp_width(bh), fbvar.xres); j++)
		{
			pixel = bmp_getpixel(bh, j, i);
			*(pfbmap+((i+offset_y)*fbvar.xres)+(j+offset_x)) = makepixel(&fbvar, pixel.r, pixel.g, pixel.b);
		}
	}

	bmp_close(bh);
	munmap(pfbmap, fbvar.xres*fbvar.yres*16/8);
	close(fbfd);

	return 0;
}


